﻿using DevExpress.ExpressApp;
using System.Text;
using System.Text.Json;
using YAPACS.BusinessObjects.Managements.Exams;
using YAPACS.Organizations;

namespace YAPACS.RisServer;

public class Column
{
    public string DataField { get; set; }
    public string Property { get; set; }
    public bool Exclude { get; set; }
    public string Order { get; set; }
    public string ArchiveOrder { get; set; }
    public string Caption { get; set; }
    public string ArchiveProperty { get; set; }
    public bool ExcludeArchive { get; set; }
}

public static class Extensions
{
    public static string GetColumnString(this Column[] columns)
    {
        var str = string.Join(',', columns.Where(e => !e.Exclude).Select(e => !string.IsNullOrWhiteSpace(e.Property) ? $"{e.Property} as {e.DataField}" : e.DataField));
        return "new (" + str + ",0 as isArchive)";
    }
    public static string GetArchiveColumnString(this Column[] columns)
    {
        var str = string.Join(',', columns.Where(e => (!e.Exclude)&&(!e.ExcludeArchive)).Select(e => !string.IsNullOrWhiteSpace(e.ArchiveProperty) ? $"{e.ArchiveProperty} as {e.DataField}" : e.DataField));
        return str+ ",1 as isArchive";
    }
    public static string GetExportColumnString(this Column[] columns)
    {
        var str = string.Join(',', columns.Where(e => !e.Exclude).Select(e => $"{(!string.IsNullOrWhiteSpace(e.Property) ? e.Property : e.DataField)} as {e.Caption}"));
        return "new (" + str + ")";
    }
    public static ExamFilter GetDefaultFilter(this ApplicationUser user, Guid groupId, ExamFilterType examFilterType)
    {
        ExamFilter defaultFilter = null;
        var os = ((IObjectSpaceLink)user).ObjectSpace;
        var group = os.GetObjectByKey<UserGroup>(groupId);
        var list = os.GetObjectsQuery<ExamFilter>().Where(e => e.IsActive && e.FilterType == examFilterType && e.Department == group.Department).OrderBy(f => f.IsDirectory ? 0 : 1).ThenBy(f => f.Order).ToList();
        var defaultList = list.Where(e => e.IsDefault && !e.IsDirectory).ToList();
        defaultFilter = defaultList.FirstOrDefault(e => e.UserGroup != null && e.UserGroup == group && e.User == user);
        defaultFilter ??= defaultList.FirstOrDefault(e => e.UserGroup == group && e.User == null);
        defaultFilter ??= defaultList.FirstOrDefault(e => e.UserGroup == null && e.User == null);
        if (defaultFilter == null)
        {
            //取第一个目录下的第一个过滤条件
            var _list = list.Where(e => e.UserGroup != null && e.UserGroup == group && e.User == user).ToList();
            defaultFilter = GetFirstFilter(_list);
            if (defaultFilter == null)
            {
                _list = list.Where(e => e.UserGroup == group && e.User == null).ToList();
                defaultFilter = GetFirstFilter(_list);
            }
            if (defaultFilter == null)
            {
                _list = list.Where(e => e.UserGroup == null && e.User == null).ToList();
                defaultFilter = GetFirstFilter(_list);
            }
        }
        return defaultFilter;
    }

    public static ExamFilter GetFirstFilter(List<ExamFilter> examFilters)
    {
        if (examFilters.Count == 0)
        {
            return null;
        }
        else
        {
            ExamFilter root = examFilters.FirstOrDefault();
            if (!root.IsDirectory)
            {
                return root;
            }
            else
            {
                return GetFirstFilter([.. root.Children]);
            }
        }
    }

    public static string Serialize<T>(this T obj, JsonSerializerDefaults jsonSerializerDefaults = JsonSerializerDefaults.Web)
    {
        return JsonSerializer.Serialize(obj, options: new(jsonSerializerDefaults));
    }
    public static T Deserialize<T>(this string json, JsonSerializerDefaults jsonSerializerDefaults = JsonSerializerDefaults.Web)
    {
        return JsonSerializer.Deserialize<T>(json, options: new(jsonSerializerDefaults));
    }
    public static bool EqualsIgnoreCase(this string target, string value)
    {
        return target.Equals(value, StringComparison.CurrentCultureIgnoreCase);
    }

    public static async Task<string> GetResourceStringAsync(string sourceName)
    {
#if DEBUG
        var names = sourceName.Split('.');
        var resourceFile = $"{Path.Combine([Directory.GetCurrentDirectory(), .. names.Take(names.Length - 1)])}.{names.Last()}";
        if (File.Exists(resourceFile))
        {
            return File.ReadAllText(resourceFile, Encoding.UTF8);
        }
        else
        {
            return await Task.FromResult(string.Empty);
        }
#else
        var assembly = System.Reflection.Assembly.GetExecutingAssembly();
        var resourceName = $"{assembly.GetName().Name}.{sourceName}";
        using var stream = assembly.GetManifestResourceStream(resourceName);
        if (stream != null)
        {
            using var reader = new StreamReader(stream, Encoding.UTF8);
            return await reader.ReadToEndAsync();
        }
        return string.Empty;
#endif
    }
    public static async Task<string> GetAsync(string url, Dictionary<string, string> headers = null)
    {
        using var client = new HttpClient();
        var request = new HttpRequestMessage(HttpMethod.Get, url);
        if (headers != null)
        {
            foreach (var header in headers)
            {
                request.Headers.Add(header.Key, header.Value);
            }
        }
        var content = new StringContent("", Encoding.UTF8, "text/plain");
        request.Content = content;
        var response = await client.SendAsync(request);
        response.EnsureSuccessStatusCode();
        var result = await response.Content.ReadAsStringAsync();
        return result;
    }
    public static async Task<F> GetAsync<F>(string url, Dictionary<string, string> headers = null)
    {
        var result = await GetAsync(url, headers);
        return JsonSerializer.Deserialize<F>(result);
    }

    public static async Task<string> PostAsync<T>(string url, T bodyParam, Dictionary<string, string> headers = null)
    {
        using var client = new HttpClient();
        var request = new HttpRequestMessage(HttpMethod.Post, url);
        if (headers != null)
        {
            foreach (var header in headers)
            {
                request.Headers.Add(header.Key, header.Value);
            }
        }
        var content = new StringContent(JsonSerializer.Serialize(bodyParam), Encoding.UTF8, "application/json");
        request.Content = content;
        var response = await client.SendAsync(request);
        response.EnsureSuccessStatusCode();
        var result = await response.Content.ReadAsStringAsync();
        return result;
    }
    public static async Task<F> PostAsync<T, F>(string url, T bodyParam, Dictionary<string, string> headers = null)
    {
        var result = await PostAsync(url, bodyParam, headers);
        return JsonSerializer.Deserialize<F>(result);
    }
}
